#ifndef _RSSSTORE_H_
#define _RSSSTORE_H_
#include <stdio.h>

typedef struct PubDate {
	unsigned int date;	/* 0xAABBCCDD = 2007.05.29 */
	unsigned int time;	/* 0xAABBCCDD = 00.	10:02:59 */
} PubDate;

typedef struct RSSFeedItem {
	struct PubDate time;
	unsigned short  len_title;
	wchar_t *title;
	unsigned short  len_description;
	wchar_t *description;
	unsigned short  len_url;
	char *url;
} RSSFeedItem;
	
typedef struct IndexFileHead {
	int version;
	unsigned short total;
	unsigned short un_read;
	struct PubDate time;
	unsigned short capacity;
	unsigned short bitmap_size;
	unsigned short num;
	unsigned short last_same_num;
	unsigned short delete_tail;
} IndexFileHead;

typedef struct IndexTable {
	unsigned short flag;
	short item;
	unsigned short time_end_size;
	unsigned short title_end_size;
	unsigned short des_end_size;
	unsigned short url_end_size;
} IndexTable;

#define TIME_POS	0
#define TITLE_POS 	(sizeof(struct PubDate ))
#define DES_POS(x)	(x.title_end_size)
#define URL_POS(x)	(x.des_end_size)

#define TIME_SIZE		(sizeof(struct PubDate ))
#define TITLE_SIZE(x)	(x.title_end_size - x.time_end_size)
#define DES_SIZE(x)		(x.des_end_size - x.title_end_size)
#define URL_SIZE(x)		(x.url_end_size - x.des_end_size)

typedef struct BlockNext {
	short next;	
} BlockNext;

#define HAS_READ	0x01
#define HAS_DEL		0x02
#define MAX_CAPACITY	100

#define IS_TIME		0x01
#define IS_TITLE		0x02
#define IS_DESC		0x04		
#define IS_URL		0x08


#define MAX_FILE_NAME		8
#define CHANNEL_TITLE_MAX	10
#define CHANNEL_URL_MAX	128

#define	BLOCK_SIZE 255
#define REAL_BLOCK_SIZE ((BLOCK_SIZE + 255) & 0xffffff00)
#define REAL_BUFFER_SIZE (REAL_BLOCK_SIZE - sizeof(struct BlockNext))

#define INDEX_HEAD_POS			0
#define INDEX_CACHE_POS			(sizeof(struct IndexFileHead))
#define INDEX_TEMP_POS(x)			(INDEX_CACHE_POS + x * sizeof(unsigned short))
#define INDEX_TABLE_POS(x)			(INDEX_CACHE_POS + 2 * x * sizeof(unsigned short))
#define INDEX_BITMAP_POS(x)		(INDEX_TABLE_POS(x) + x * sizeof(struct IndexTable))
#define BLOCK_BITMAP_POS(x)		(INDEX_BITMAP_POS(x) + 4*(x + 31)/32)

//update state
#define UPDATEDE_NOT_READ		0x1000
#define UPDATEDE_AND_READ   	0x2000
#define UPDATING				0x4000
#define UPDATEDE_ERR			0x8000
//item read state
#define ITEM_READ				0x01
#define ITEM_NOT_READ			0x02
//
#define DELETE_ALL_ITEMS  0
#define DELETE_READ_ITEMS  1

typedef struct RSSChannel_Head {
	unsigned short total;
	unsigned short has_rebuild;
} RSSChannel_Head;

typedef struct RSSFeedChannel{
	struct PubDate updateTime;
	short totleItems;
	short unreadItems;
	wchar_t  title[CHANNEL_TITLE_MAX + 1];	
	short updateStat;
	short inteval;
	short url_len;
	char name[MAX_FILE_NAME];
	char *url;
} RSSFeedChannel;

#define int8 signed char
#define uint8 unsigned char

short RSSParserCallBack(struct RSSFeedItem *pItem, void *pContext);
typedef short (*RSSCALLBACK)(struct RSSFeedItem *pItem, void *pContext);
short RSSParse(char *file, RSSCALLBACK pCallback, void *pContext);

typedef struct RSSParserGlobal{
	RSSCALLBACK StoreOneItem;
	void *Store_rss_channel;
} RSSParserGlobal;

int _Utf8ToUnicode(wchar_t *to, const char *from, int lens);
int _UnicodeToUtf8(char *to, const wchar_t *from, int need, int *buffer_lens);
static short CompareTime(struct PubDate *t1, struct PubDate *t2);
static short FindFirstUnused(int bitmap);
static short FindFirstUnused(int bitmap);
static short FindFirstBitmap(char *index, int is_index);
static short FreeBitmap(char *index, short index_num, int is_index);
int RSSItemStorage_Create(char *index, char *feed, unsigned short capacity);
static short RSSItemStorage_Link(char *index,  short index_num);
static short RSSItemStorage_Unlink(unsigned short channel, char *index, short index_num);
static short get_file_name(unsigned short channel, char *index, char *feed);
static short refresh_channel_stat(unsigned short channel, struct IndexFileHead *head, unsigned short refresh_stat);
int8 SMergeUpdateChannel(unsigned short channel);
short RSSItemStorage_Add(unsigned short channel, struct RSSFeedItem *item);
static short RSSItemStorage_Remove(unsigned short channel, char *index, char *feed, unsigned short index_num);
static short RSSItemStorage_Remove_Tail(unsigned short channel, char *index, char *feed);
void FreeItem(struct RSSFeedItem *rss_item);
short RSSItemExist(unsigned short channel, struct RSSFeedItem *item);
int8 ReadFeedItem(unsigned short  channel, unsigned short  index_num, struct RSSFeedItem *item, uint8 flag);
static short _RSSItemList_Remove(char *index, char *feed, short feed_index);
static short _ReadOneItem(char *feed, short index, unsigned short pos, unsigned short size, void *buf);
static short _WriteFeedItem(char *index, char *feed, unsigned short capacity, unsigned short index_num, struct RSSFeedItem *item);
static short _ReadFeedItem(char *index, char *feed, struct RSSFeedItem *item, unsigned short index_num, uint8 flag, unsigned short from_temp);
short ReadChannelNums(void);
short ReadItemNums(unsigned short channel);
int8 ReadFeedChannel(unsigned short channel, struct RSSFeedChannel *pCh);
int8 ReadChannelURL(unsigned short channel, struct RSSFeedChannel * pCh);
short SAddFeedChannel(struct RSSFeedChannel * pCh);
short WriteFeedChannel(unsigned channel, struct RSSFeedChannel *pCh);
int8 SDeleteFeedChannel(unsigned short channel);
short ChangeFeedChannel(unsigned channel, wchar_t *title, char *url);
short _AddFeedChannel(wchar_t *title, char *url);
short WriteFeedChannel_WithoutUrl(unsigned channel, struct RSSFeedChannel *pCh);
int8 SDeleteItems(unsigned short channel, uint8 flag);
int8 SSetItemAsRead(unsigned short channel, unsigned short index_num);
int8 SDeleteFeedItem(unsigned short channel, unsigned short index_num);
short InitChannel(void);

void rss_test(void);

#endif
